/*
 * All content copyright http://www.j2eefast.com, unless
 * otherwise indicated. All rights reserved.
 * No deletion without permission
 */
package com.j2eefast.framework.sys.service;

import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.j2eefast.common.core.constants.ConfigConstant;
import com.j2eefast.common.core.enums.OperationEventType;
import com.j2eefast.common.core.page.Query;
import com.j2eefast.common.core.utils.PageUtil;
import com.j2eefast.common.core.utils.SpringUtil;
import com.j2eefast.common.core.utils.ToolUtil;
import com.j2eefast.common.event.SysDictEvent;
import com.j2eefast.framework.redis.SysConfigRedis;
import com.j2eefast.framework.sys.entity.SysDictDataEntity;
import com.j2eefast.framework.sys.mapper.SysDictDataMapper;
import com.j2eefast.framework.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 数据字典
 */
@Service
public class SysDictDataService  extends ServiceImpl<SysDictDataMapper,SysDictDataEntity> {

	@Autowired
	private SysConfigRedis sysConfigRedis;

	/**
	 * 页面展示查询翻页
	 */
	public PageUtil findPage(Map<String, Object> params) {
		String dictLabel = (String) params.get("dictLabel");
		String dictType = (String) params.get("dictType");
		String status = (String) params.get("status");
		String appNo = (String) params.get("appNo");
		LambdaQueryWrapper<SysDictDataEntity> wrapper = SysDictDataEntity.gw();
		wrapper.like(ToolUtil.isNotEmpty(dictLabel),SysDictDataEntity::getDictLabel,dictLabel);
		wrapper.eq(ToolUtil.isNotEmpty(dictType),SysDictDataEntity::getDictType,dictType);
		wrapper.eq(ToolUtil.isNotEmpty(status),SysDictDataEntity::getStatus,status);
		wrapper.eq(ToolUtil.isNotEmpty(appNo),SysDictDataEntity::getAppNo,appNo);
		Page<SysDictDataEntity> page = this.baseMapper.selectPage(new Query<SysDictDataEntity>(params).getPage(), wrapper);
		return new PageUtil(page);
	}

	public List<SysDictDataEntity> selectDictDataByType(String dictType, String appNo) {
		//1.先获取系统字典
		List<SysDictDataEntity>  list = Constant.SYS_DICT.get(appNo + StrPool.COLON+ dictType);
		if(ToolUtil.isNotEmpty(list)){
			return list;
		}
		//2.获取缓存
		list = sysConfigRedis.getRedisDict(appNo+StrPool.COLON + dictType);
		if(ToolUtil.isEmpty(list)){
			list =  this.list(SysDictDataEntity.gw().select(SysDictDataEntity::getId,SysDictDataEntity::getAppNo,
					SysDictDataEntity::getDictSort,SysDictDataEntity::getDictLabel,
					SysDictDataEntity::getDictType,SysDictDataEntity::getDictValue,
					SysDictDataEntity::getIsDefault,SysDictDataEntity::getCssClass,
					SysDictDataEntity::getCssStyle, SysDictDataEntity::getListClass,
					SysDictDataEntity::getDelFlag, SysDictDataEntity::getStatus,
					SysDictDataEntity::getIsSys)
					.eq(SysDictDataEntity::getDictType,dictType)
					.eq(SysDictDataEntity::getStatus,"0")
					.eq(SysDictDataEntity::getAppNo,appNo)
					.orderBy(true, true, SysDictDataEntity::getDictSort));
			Optional.ofNullable(list).ifPresent(t->{
				Constant.SYS_DICT.put(appNo+StrPool.COLON+dictType,t);
				sysConfigRedis.saveOrUpdateDict(appNo+StrPool.COLON+dictType,t);
			});
			return list;
		}else{
			list = JSON.parseArray(JSON.toJSONString(list),SysDictDataEntity.class);
			return list;
		}
	}

	/**
	 * 添加/更新 系统缓存字典
	 * @param dictType
	 * @param dictData
	 */
	public void saveOrUpdateSysDict(String dictType, SysDictDataEntity dictData){
		ConfigConstant.DICT_TAG = RandomUtil.randomString(5);
		List<SysDictDataEntity>  list = Constant.SYS_DICT.get(dictData.getAppNo()+StrPool.COLON+dictType);
		if(ToolUtil.isEmpty(list)){
			list = new ArrayList<>();
			if(dictData.getStatus().equals("0")){
				list.add(dictData);
				Constant.SYS_DICT.put(dictData.getAppNo()+StrPool.COLON+dictType,list);
			}
		}else{
			//循环匹配找到删除
			for (Iterator<SysDictDataEntity> dicts = list.iterator(); dicts.hasNext();) {
				SysDictDataEntity dict =  dicts.next();
				if(StrUtil.equalsIgnoreCase(dictData.getAppNo()+StrPool.COLON+dict.getDictValue(),
						dictData.getAppNo()+StrPool.COLON+dictData.getDictValue())){
					dicts.remove();
				}
			}
			if(dictData.getStatus().equals("0")){
				list.add(dictData);
				Constant.SYS_DICT.put(dictData.getAppNo()+StrPool.COLON+dictType,list);
			}
		}
	}

	public void delByIdSysDict(String dictType,String appNo, Long id){
		ConfigConstant.DICT_TAG = RandomUtil.randomString(5);
		List<SysDictDataEntity>  list = Constant.SYS_DICT.get(appNo+StrPool.COLON+dictType);
		if(ToolUtil.isNotEmpty(list)){
			for (Iterator<SysDictDataEntity> dicts = list.iterator(); dicts.hasNext();) {
				SysDictDataEntity dict =  dicts.next();
				if(id.equals(dict.getId())){
					dicts.remove();
				}
			}
		}
	}

	public void delByValueSysDict(String dictType,String appNo, String dictValue){
		ConfigConstant.DICT_TAG = RandomUtil.randomString(5);
		List<SysDictDataEntity>  list = Constant.SYS_DICT.get(appNo+StrPool.COLON+dictType);
		if(ToolUtil.isNotEmpty(list)){
			for (Iterator<SysDictDataEntity> dicts = list.iterator(); dicts.hasNext();) {
				SysDictDataEntity dict =  dicts.next();
				if(dictValue.equals(dict.getDictValue())){
					dicts.remove();
				}
			}
		}
	}

	public String selectDictLabel(String dictType,String appNo, String dictValue) {
		List<SysDictDataEntity>  list = Constant.SYS_DICT.get(appNo+StrPool.COLON+dictType);
		if(ToolUtil.isEmpty(list)){
			list = sysConfigRedis.getRedisDict(appNo+StrPool.COLON+dictType);
			if(ToolUtil.isEmpty(list)){
				return this.baseMapper.selectDictLabel(appNo,dictType,dictValue);
			}
		}
		String r = "";
		List<SysDictDataEntity> list1 = JSON.parseArray(JSON.toJSONString(list),SysDictDataEntity.class);
		for(SysDictDataEntity dict: list1){
			if(dict.getDictValue().equals(dictValue)){
				r = dict.getDictLabel();
				break;
			}
		}
		return r;
	}

	public long countDictDataByType(String dictType,String appNo) {
		return this.count(SysDictDataEntity.gw().eq(SysDictDataEntity::getDictType,dictType)
				.eq(SysDictDataEntity::getAppNo,appNo));
	}

	public boolean updateDictData(SysDictDataEntity dictData) {
		boolean r =  this.updateById(dictData);
		List<SysDictDataEntity>  list = this.list(SysDictDataEntity.gw()
				.eq(SysDictDataEntity::getDictType,dictData.getDictType())
				.eq(SysDictDataEntity::getStatus,"0")
				.eq(SysDictDataEntity::getAppNo,dictData.getAppNo())
				.orderBy(true, true, SysDictDataEntity::getDictSort));
		sysConfigRedis.saveOrUpdateDict(dictData.getAppNo()+StrPool.COLON+dictData.getDictType(),list);
		SysDictEvent event  = new SysDictEvent(dictData);
		event.setAppNo(dictData.getAppNo());
		event.setDictType(dictData.getDictType());
		event.setOperationEventType(OperationEventType.UPDATE);
		SpringUtil.publishEvent(event);
		return r;
	}

	public boolean deleteBatchByIds(Long[] ids) {
		SysDictDataEntity dict = this.getById(ids[0]);
		this.baseMapper.deleteDictDataByIds(ids);
		List<SysDictDataEntity>  list = this.list(SysDictDataEntity.gw()
				.eq(SysDictDataEntity::getDictType,dict.getDictType())
				.eq(SysDictDataEntity::getStatus,"0")
				.eq(SysDictDataEntity::getAppNo,dict.getAppNo())
				.orderBy(true, true, SysDictDataEntity::getDictSort));
		if(ToolUtil.isEmpty(list)){
			sysConfigRedis.delRedisDict(dict.getAppNo()+StrPool.COLON+dict.getDictType());
		}else{
			sysConfigRedis.saveOrUpdateDict(dict.getAppNo()+StrPool.COLON+dict.getDictType(),list);
		}
		SysDictEvent event  = new SysDictEvent(dict);
		event.setAppNo(dict.getAppNo());
		event.setDictType(dict.getDictType());
		event.setOperationEventType(OperationEventType.DEL);
		SpringUtil.publishEvent(event);
		return true;
	}

}
